package test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.TermFreqVector;
import org.apache.lucene.search.function.CustomScoreProvider;

public class CirCustomScoreProvider extends CustomScoreProvider {

	private float ALPHA;
	private float cenx;
	private float ceny;
	private float radi;
	private float ds;
	private List<String> terms = new ArrayList<String>();
	private List<Document> cirDocs = new ArrayList<Document>();
	private HashMap<String, Integer> hm = new HashMap<String, Integer>();

	public CirCustomScoreProvider(IndexReader reader, float ALPHA, float cenx, float ceny, float radi, 
			float ds, List<String> terms, List<Document> cirDocs, HashMap<String, Integer> hm) {
		super(reader);
		// TODO Auto-generated constructor stub
		this.ALPHA = ALPHA;
		this.cenx = cenx;
		this.ceny = ceny;
		this.radi = radi;
		this.ds = ds;
		this.terms = terms;
		this.cirDocs = cirDocs;
		this.hm = hm;
	}

	@Override
	public float customScore(int doc, float subQueryScore, float valSrcScore)
			throws IOException {
		// TODO Auto-generated method stub
		float cir = 0;
		TermFreqVector tfv = reader.getTermFreqVector(doc, "content");
		for(int k = 0; k < cirDocs.size(); k++){
			if(cirDocs.get(k).get("name").equals(reader.document(doc).get("name"))){
				for(int i = 0; i < terms.size(); i++){
					int index = tfv.indexOf(terms.get(i));
					if(index!=-1){
						int occ = tfv.getTermFrequencies()[index];
						float tf = (float) (1 + Math.log10(occ));
						int df = hm.get(terms.get(i));
						if(df != 0){
							float idf = (float) Math.log10(ds / df);
							cir += tf * idf;
						}
					}
				}
			}
		}

		float docx = Float.parseFloat(reader.document(doc).get("x"));
		float docy = Float.parseFloat(reader.document(doc).get("y"));
		float dist = (float) Math.sqrt(Math.pow(cenx - docx, 2) + Math.pow(ceny - docy, 2));
		float dismax = radi; 
		float sp = 1 - dist / dismax;
		float score = ALPHA * cir + (1 - ALPHA) * sp;
		return score;
	}
}
